﻿using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.Domain.Repositories;
using Abp.Extensions;
using Abp.Json;
using Abp.Linq.Extensions;
using Abp.Runtime.Session;
using Microsoft.EntityFrameworkCore;
using Mt.Site.Application.CustomConfigurations.Dto;
using Mt.Site.Application.Dto;
using Mt.Site.Core.BackGroundJobs.ContentManagement;
using Mt.Site.Core.BackGroundJobs;
using Mt.Site.Core.ContentManagement.Permissions;
using Mt.Site.Core.CustomConfigurations;
using Mt.Site.Core.CustomConfigurations.Config;
using Mt.Site.Core.CustomConfigurations.Permissions;
using Mt.Site.Core.Synchronization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using Mt.Site.Core.DataLogs;

namespace Mt.Site.Application.CustomConfigurations
{
    public class CustomConfigAppService : MtSiteAppServiceBase, ICustomConfigAppService
    {
        private readonly ICustomConfigStore _customConfigStore;
        private readonly ICustomConfigManager _customConfigManager;
        private readonly ICustomConfigFile _customConfigFile;
        private readonly IRepository<CustomConfiguration, Guid> _customConfigurationRepository;

        public CustomConfigAppService(
            ICustomConfigStore customConfigStore,
            ICustomConfigManager customConfigManager,
            ICustomConfigFile customConfigFile,
            IRepository<CustomConfiguration, Guid> customConfigurationRepository)
        {
            _customConfigStore = customConfigStore;
            _customConfigManager = customConfigManager;
            _customConfigFile = customConfigFile;
            _customConfigurationRepository = customConfigurationRepository;
        }

        [AbpAuthorize(CustomConfigPermissions.Pages_Administration_CustomConfigs_Create)]
        public async Task CreateAsync(CreateCustomConfigDto input)
        {
            var m =  ObjectMapper.Map<CustomConfiguration>(input);
            await _customConfigStore.CreateAsync(m);
        }

        [AbpAuthorize(CustomConfigPermissions.Pages_Administration_CustomConfigs_Delete)]
        public async Task DeleteAsync(EntityDto<Guid> input)
        {
            await _customConfigStore.DeleteAsync(input.Id);
        }

        [AbpAuthorize(CustomConfigPermissions.Pages_Administration_CustomConfigs_Delete)]
        public async Task DeleteListAsync(List<Guid> input)
        {
            await _customConfigStore.DeleteListAsync(input);
        }

        [AbpAuthorize(CustomConfigPermissions.Pages_Administration_CustomConfigs)]
        public async Task<CustomConfigDto> GetAsync(EntityDto<Guid> input)
        {
            var entity = await _customConfigStore.GetAsync(input.Id);
            return ObjectMapper.Map<CustomConfigDto>(entity);
        }

        [AbpAuthorize(CustomConfigPermissions.Pages_Administration_CustomConfigs)]
        public async Task<PagedResultDto<PagedCustomConfigDto>> GetPagedCustomConfigs(PagedCustomConfigInput input)
        {
            var query = _customConfigurationRepository.GetAll()
            .WhereIf(!input.Filter.IsNullOrEmpty(), t => t.Name.Contains(input.Filter));

            query = !input.Sorting.IsNullOrEmpty() ? query.OrderBy(input.Sorting) : query.OrderByDescending(t => t.CreationTime);

            var count = query.Count();
            var list = await query.PageBy(input).ToListAsync();
            return new PagedResultDto<PagedCustomConfigDto>(count, ObjectMapper.Map<List<PagedCustomConfigDto>>(list));
        }


        [AbpAuthorize]
        public async Task<PagedResultDto<ConfigDataItem>> GetPagedConfigDatasByTypeAsync(GetPagedConfigDatasInput input)
        {
            var query = _customConfigurationRepository.GetAll()
                .Where(c=> c.DataType == input.DataType && c.IsActive)
                .WhereIf(!input.Filter.IsNullOrEmpty(), t => t.Name.Contains(input.Filter));

            query = !input.Sorting.IsNullOrEmpty() ? query.OrderBy(input.Sorting) : query.OrderByDescending(t => t.CreationTime);

            var count = query.Count();
            var list = await query.PageBy(input).ToListAsync();

            var list2 = list.Select(c =>
            {
                var key = _customConfigFile.GetCustomKeyById(c.Id);
                key = key ?? "未找到配置名";
                return new ConfigDataItem
                {
                    Name = c.Name,
                    Id = c.Id,
                    CustomKey = key,
                    Description = c.Description,
                    CreationTime = c.CreationTime,
                    DataType = c.DataType,
                    Key = c.Key
                };
            }).ToList();

            return new PagedResultDto<ConfigDataItem>(count, list2);
        }

        [AbpAuthorize(CustomConfigPermissions.Pages_Administration_CustomConfigs_Edit)]
        public async Task UpdateAsync(UpdateCustomConfigDto input)
        {
            var m = await _customConfigStore.GetAsync(input.Id);
            AppCheck.CheckLastModificationTime(input.LastModificationTime, m, L("DataHasBeenChanged"));
            m.Name = input.Name;
            m.Description = input.Description;
            m.ExtensionData = input.ExtensionData;
            m.DataType = input.DataType;
            m.Key = input.Key;
            m.IsActive = input.IsActive;
            await _customConfigStore.UpdateAsync(m);
        }

        [AbpAuthorize(CustomConfigPermissions.Pages_Administration_CustomConfigs_Edit)]
        public async Task SetStatusAsync(SetStatusInput input)
        {
            var list = await _customConfigurationRepository.GetAllListAsync(c => input.IdList.Contains(c.Id));

            foreach (var item in list)
            {
                item.IsActive = input.IsActive;
            }
        }

        [AbpAuthorize]
        public async Task<string> GetConfigAsync(GetConfigInput input)
        {
            return await _customConfigManager.GetConfigStrAsync(input.CustomKey);
        }

        [AbpAuthorize(CustomConfigPermissions.Pages_Administration_CustomConfigs_ConfigFileEdit)]
        public async Task UpdateOrCreateConfigFileAsync(ConfigFileDto input)
        {
            await _customConfigFile.UpdateOrCreateConfigFileAsync(input.Content);
        }

        [AbpAuthorize(CustomConfigPermissions.Pages_Administration_CustomConfigs_ConfigFileEdit)]
        public async Task<string> GetConfigFileContentAsync()
        {
            return await _customConfigFile.GetConfigFileContentAsync();
        }

        [AbpAuthorize(CustomConfigPermissions.Pages_Administration_CustomConfigs_ConfigFileEdit)]
        public async Task<string> GeneralConfigFileAsync()
        {
            var configStr = await GetConfigFileContentAsync();

            var data = configStr.FromJsonString<CustomConfigData>();

            var temp = new Dictionary<string, Guid>();

            var entities = await _customConfigurationRepository.GetAll()
                .Where(t => t.IsActive && !string.IsNullOrEmpty(t.Key))
                .OrderBy(t => t.CreationTime)
                .ToListAsync();

            foreach (var item in data.Custom)
            {
                if (!temp.ContainsKey(item.Key))
                {
                    temp.Add(item.Key, item.Value);
                }
            }

            foreach (var item in entities)
            {
                if (!temp.ContainsKey(item.Key))
                {
                    temp.Add(item.Key, item.Id);
                }
            }

            var newData = new
            {
                Custom = temp
            };

            var newConfigStr = newData.ToJsonString();

            await UpdateOrCreateConfigFileAsync(new ConfigFileDto { Content = newConfigStr });

            return newConfigStr;
        }
    }
}
